package com.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dao.SysUser;
import com.dao.dto.SysUserUpdateDTO;
import com.mapper.SysPermissionMapper;
import com.mapper.SysUserMapper;
import com.service.SysUserService;
import com.utils.ErrorCode;
import com.utils.JWTUtils;
import com.utils.RandomStringGenerator;
import com.utils.Result;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class SysUserServiceImpl implements SysUserService {

    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private SysPermissionMapper sysPermissionMapper;
    //加密盐用于加密
    private static final String SALT = "mszlu!@#";
    /**
     * 1.判断参数是否合法
     * 2.判断账户是否存在，存在  返回账户已经被注册
     * 3.如果账户不存在，注册用户
     * 4.生成token
     * 6. 注意：加上事务，一旦中间任何过程出现问题，注册的用户 需要回滚
     */
    @Transactional
    @Override
    public Result registryLogin(SysUser sysUser) {
        String account = sysUser.getAccount();
        String password = sysUser.getPassword();
        String nickname = sysUser.getNickname();
        if(StringUtils.isBlank(account) || StringUtils.isBlank(password)|| StringUtils.isBlank(nickname)){
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }

        LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysUser::getAccount,account);
        lambdaQueryWrapper.last("limit 1");
        SysUser sysUserLogin = sysUserMapper.selectOne(lambdaQueryWrapper);
        if(ObjectUtils.isNotEmpty(sysUserLogin)){
            return  Result.fail(ErrorCode.ACCOUNT_EXIST.getCode(),ErrorCode.ACCOUNT_EXIST.getMsg());
        }
        //密码使用md5加密  为了更加的安全在加一个加密盐
        String salt = RandomStringGenerator.generateRandomString(36);
        sysUser.setPassword(DigestUtils.md5Hex(password + salt));
        sysUser.setCreateTime(LocalDateTime.now());
        sysUser.setLastLogin(LocalDateTime.now());
        sysUser.setAdmin(1); //1为true
        sysUser.setIsDeleted(0);  //0为false
        sysUser.setSalt(salt);
        sysUserMapper.insert(sysUser);
        String token = JWTUtils.createUserIdToken(sysUser.getId());
        return Result.success(token);
    }


    /**
     * 1.检查参数是否合法
     * 2.根据用户名和密码去user表中查询是否存在
     * 3.如果不存在   登录失败
     * 4. 如果存在  ，使用jwt生成token 返回给前端
     */
    @Override
    public Result login(SysUser sysUser) {
        String account = sysUser.getAccount();
        String password = sysUser.getPassword();
        if (StringUtils.isBlank(account) || StringUtils.isBlank(password)){
            return  Result.fail(ErrorCode.PARAMS_ERROR.getCode(),ErrorCode.PARAMS_ERROR.getMsg());
        }
        LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysUser::getAccount,account);
        SysUser sysUser2 = sysUserMapper.selectOne(lambdaQueryWrapper);
        if(ObjectUtils.isEmpty(sysUser2)){
            return Result.fail(ErrorCode.ACCOUNT_NOT_EXIST.getCode(), ErrorCode.ACCOUNT_NOT_EXIST.getMsg());
        }
        String realSalt = sysUser2.getSalt();
        //把密码加密一下
        String pwd = DigestUtils.md5Hex(password + realSalt);
        lambdaQueryWrapper.eq(SysUser::getPassword,pwd);
        lambdaQueryWrapper.select(SysUser::getAccount,
                SysUser::getId,
                SysUser::getAvatar,
                SysUser::getNickname,
                SysUser::getMobilePhoneNumber,
                SysUser::getEmail,
                SysUser::getAdmin);
        lambdaQueryWrapper.last("limit 1"); //保证一下查询效率   要不然可能还会一直往下查询
        SysUser sysUser1 =  sysUserMapper.selectOne(lambdaQueryWrapper);
        if(ObjectUtils.isEmpty(sysUser1)){
            return Result.fail(ErrorCode.ACCOUNT_PWD_NOT_EXIST.getCode(),ErrorCode.ACCOUNT_PWD_NOT_EXIST.getMsg());
        }

        //根据用户id，拿到权限集合
        Long sysUserId = sysUser1.getId();
        Integer admin = sysUser1.getAdmin();
        List<String> permissions;
        if(1 == admin){
            permissions = sysPermissionMapper.getAllPermissions();
        }else {
            permissions = sysPermissionMapper.getPermissonsByUserId(sysUserId);
        }

        //登录成功，使用JWT生成token，返回token和redis中
        //String token = JWTUtils.createUserIdToken(sysUser1.getId());
        String token = JWTUtils.createUserToken(sysUser1);
        Map map = new HashMap();
        map.put("token", token);
        map.put("permissions", permissions);
        return Result.success(map);
    }

    @Transactional
    @Override
    public Result updatePwd(SysUserUpdateDTO sysUserUpdateDTO) {
        String account = sysUserUpdateDTO.getAccount();
        String password = sysUserUpdateDTO.getPassword();

        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("account",account);
        SysUser sysUser = sysUserMapper.selectOne(wrapper);
        if(ObjectUtils.isEmpty(sysUser)){
            return Result.fail("账号错误");
        }
        String salt = sysUser.getSalt();
        String oldPassword = sysUser.getPassword();
        String saltPassword = DigestUtils.md5Hex(password + salt);
        if(!oldPassword.equals(saltPassword)){
            return Result.fail("原始密码错误");
        }

        String newSalt = RandomStringGenerator.generateRandomString(36);
        String newPassword = sysUserUpdateDTO.getNewPassword();
        sysUser.setPassword(DigestUtils.md5Hex(newPassword + newSalt));
        sysUser.setSalt(newSalt);
        int i = sysUserMapper.updateById(sysUser);
        return Result.success("修改密码成功," + ErrorCode.ANEW_LOGIN.getMsg()).setCode(ErrorCode.ANEW_LOGIN.getCode());
    }


}
